import { GameObject } from "../game_object/base.js";

export class Player extends GameObject {
    constructor(root, info) {
        super();

        this.root = root;

        this.id = info.id;
        this.x = info.x;
        this.y = info.y;
        this.width = info.width;
        this.height = info.height;
        this.direction = 1; // 1为正方向，-1为负方向
        this.color = info.color;

        this.vx = 0;
        this.vy = 0;

        this.ax = info.ax; // 平移的速度
        this.ay = info.ay; // 起跳的初速度

        this.gravity = 50;

        this.ctx = this.root.game_map.ctx;
        this.pressed_keys = this.root.game_map.controller.pressed_keys;

        this.status = 3; // 0: idle, 1: 向前，2：向后（1，2合并为一个1：移动，在渲染时才区分前进后退），3：跳跃，4：攻击，5：被打，6：死亡
        this.animations = new Map(); // 保存要渲染图片的信息
        this.cur_frame_cnt = 0;
        this.attack = 20;

        this.max_hp = 100; // 最大血量
        this.hp = this.max_hp; // 当前血量
        this.$hp = this.root.$kof_header.find(`.kof-header-hp${this.id}`);
        this.$hp_outer = this.$hp.find(".outer-hp");
        this.$hp_inner = this.$hp_outer.find(".inner-hp");

        this.restart_delta = 1000;
    }



    update_control() {
        this.restart_delta += this.time_delta;
        if (this.is_restart() && this.restart_delta > 1000) {
            this.root.restart();
            this.restart_delta = 0;
        }

        let l, r, jump, attack;

        if (this.id === 0) {
            l = this.pressed_keys.has('a') || this.pressed_keys.has('A');
            r = this.pressed_keys.has('d') || this.pressed_keys.has('D');
            jump = this.pressed_keys.has('w') || this.pressed_keys.has('W');
            attack = this.pressed_keys.has('j') || this.pressed_keys.has('J');
        } else {
            l = this.pressed_keys.has('ArrowLeft');
            r = this.pressed_keys.has('ArrowRight');
            jump = this.pressed_keys.has('ArrowUp');
            attack = this.pressed_keys.has('End') || this.pressed_keys.has('1');
        }

        // 只有在静止和移动状态时可以输入指令
        if (this.status === 0 || this.status === 1) {
            if (attack) {
                this.status = 4;
                this.vx = 0;
                this.cur_frame_cnt = 0;
            } else if (jump) {
                if (l) {
                    this.vx = -this.ax;
                } else if (r) {
                    this.vx = this.ax;
                } else {
                    this.vx = 0;
                }
                this.vy = this.ay;
                this.cur_frame_cnt = 0;
                this.status = 3;
            } else if (l) {
                this.vx = -this.ax;
                this.status = 1;
            } else if (r) {
                this.vx = this.ax;
                this.status = 1;
            } else {
                this.vx = 0;
                this.status = 0;
            }
        }

        // console.log(this.id, this.vx)
    }

    update_move() {
        this.vy += this.gravity;
        this.x += this.vx * this.time_delta / 1000;
        this.y += this.vy * this.time_delta / 1000;

        if (this.y > 450) {
            this.y = 450;
            this.vy = 0;
            if (this.status == 3) this.status = 0;
        }

        let [me, you] = [this.root.players[this.id], this.root.players[1- this.id]];
        let v1 = {
            x1: me.x,
            y1: me.y,
            x2: me.x + me.width,
            y2: me.y + me.height,
        };

        let v2 = {
            x1: you.x,
            y1: you.y,
            x2: you.x + you.width,
            y2: you.y + you.height,
        };


        // 移动碰撞检测在竖直方向会有bug
        // TODO
        // if (this.is_collision(v1, v2)) {
        //     me.x -= me.vx * me.time_delta / 1000 / 2;
        //     if (me.x < you.width || me.x > this.root.game_map.$canvas.width() - you.width - me.width) {
        //         me.x -= me.vx * me.time_delta / 1000 / 2;
        //     }
        //     if (this.status !== 6) you.x += me.vx * me.time_delta / 1000;
        // }
        // console.log(this.y);

        if (this.x < 0) {
            this.x = 0;
        } else if (this.x > this.root.game_map.$canvas.width() - this.width) {
            this.x = this.root.game_map.$canvas.width() - this.width;
        }  
    }

    update_direction() {
        if (this.status === 6) return;
        let players = this.root.players;
        let me = players[this.id], you = players[1 - this.id];

        if (me && you) {
            if (me.x > you.x) this.direction = -1;
            else this.direction = 1;
        }
    }

    // 这里使用为了方便使用硬编码将帧数固定
    // TODO：update相关的具体实现应该在具体人物类中实现，解耦合，方便扩展
    update_attack() {
        if (this.status !== 4 || this.cur_frame_cnt !== 18) return;
        let players = this.root.players;
        let me = players[this.id], you = players[1 - this.id];
        let v1, v2;

        if (me && you) {
            if (this.direction === 1) {
                v1 = {
                    x1: me.x + me.width,
                    y1: me.y + 40,
                    x2: me.x + me.width + 100,
                    y2: me.y + 40 + 20,
                }
            } else {
                v1 = {
                    x1: me.x - 100,
                    y1: me.y + 40,
                    x2: me.x - 100 + 100,
                    y2: me.y + 40 + 20,
                }
            }

            v2 = {
                x1: you.x,
                y1: you.y,
                x2: you.x + you.width,
                y2: you.y + you.height,
            }
            
            if (this.is_collision(v1, v2)) {
                you.is_attack();
            }
        }
    }

    update() {
        this.update_control();
        this.update_attack();
        this.update_move();
        this.update_direction();

        this.render();
    }

    is_restart() {
        if (this.pressed_keys.has('r') || this.pressed_keys.has('R')) {
            return true;
        }
        return false;
    }

    is_attack() {
        if (this.status === 6) return;

        this.status = 5;
        this.vx = 0;
        this.cur_frame_cnt = 0;

        this.hp = Math.max(0, this.hp - this.attack);
        
        if (this.hp <= 0) {
            this.status = 6;
            this.vx = 0;
            this.cur_frame_cnt = 0;
        }
        // console.log(this.$hp);
        // console.log(this.$hp_outer);
        // this.$hp_outer.width(this.$hp.width() * this.hp / this.max_hp);
        this.flush_hp();
    }

    flush_hp() {
        console.log('call')
        this.$hp_outer.animate({
            width: this.$hp.width() * this.hp / this.max_hp,
        }, 600);
        this.$hp_inner.animate({
            width: this.$hp.width() * this.hp / this.max_hp,
        }, 300);
    }

    is_collision(v1, v2) {
        if (Math.max(v1.x1, v2.x1) > Math.min(v1.x2, v2.x2)) return false;
        if (Math.max(v1.y1, v2.y1) > Math.min(v1.y2, v2.y2)) return false;
        
        return true;
    }

    display_hitbox() {
        this.ctx.fillStyle = 'blue';
        this.ctx.fillRect(this.x, this.y, this.width, this.height);
        this.ctx.fillStyle = 'red';

        if (this.direction > 0) {
            this.ctx.fillRect(this.x + this.width, this.y + 40, 100, 20);
        } else {
            this.ctx.fillRect(this.x - 100, this.y + 40, 100, 20)
        }
    }

    render() {
        // this.ctx.fillStyle = this.color;
        // this.ctx.fillRect(this.x, this.y, this.width, this.height);
        let cur_status = this.status;
        if (this.status === 1 && this.direction * this.vx < 0) cur_status = 2;

        // this.display_hitbox();

        let obj = this.animations.get(cur_status);
        if (obj && obj.loaded) {
            let k = parseInt(this.cur_frame_cnt / obj.frame_rate) % obj.frame_cnt;
            // console.log(k);
            if (this.direction === 1) {
                let image = obj.gif.frames[k].image;
                this.ctx.drawImage(image, this.x, this.y + obj.offset_y, image.width * obj.scale, image.height * obj.scale);
            } else {
                this.ctx.save();

                // 水平方向反转canvas坐标系
                this.ctx.scale(-1, 1);
                this.ctx.translate(-this.root.game_map.$canvas.width(), 0);

                let image = obj.gif.frames[k].image;
                this.ctx.drawImage(image, this.root.game_map.$canvas.width() - this.x - this.width, this.y + obj.offset_y, image.width * obj.scale, image.height * obj.scale);

                this.ctx.restore();
            }
        }

        if (cur_status === 4 || cur_status === 5 || cur_status === 6) {
            if (this.cur_frame_cnt === obj.frame_cnt * obj.frame_rate - 1) {
                // console.log(cur_status);
                if (cur_status === 6) {
                    this.cur_frame_cnt--;
                } else {
                    this.status = 0;
                    this.cur_frame_cnt = 0;

                }
            }
            
        }
        this.cur_frame_cnt++;

        // if (this.status === 6) {
        //     console.log(this.cur_frame_cnt);
        // }
    }

    destroy() {

    }
}